package com.runda.sec;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException;

import com.bbjob.model.SysOrganization;
import com.runda.entity.JwtUser;
import com.runda.system.service.OrganService;

public class CustomAuthenticationProvider implements AuthenticationProvider{
	private UserDetailsService userDetailsService;
	private OrganService organService;
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    public CustomAuthenticationProvider(UserDetailsService userDetailsService, BCryptPasswordEncoder bCryptPasswordEncoder,OrganService organService){
        this.userDetailsService = userDetailsService;
        this.bCryptPasswordEncoder = bCryptPasswordEncoder;
        this.organService=organService;
    }

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        // 获取认证的用户名 & 密码
        String name = authentication.getName();
        String password = authentication.getCredentials().toString();
        String oriCode=null;
        if(authentication instanceof CustomUsernamePasswordAuthenticationToken) {
        	CustomUsernamePasswordAuthenticationToken customAuthentication=(CustomUsernamePasswordAuthenticationToken)authentication;
        	oriCode=customAuthentication.getOriUnqueCode();
        }
        // 认证逻辑
        UserDetails userDetails = userDetailsService.loadUserByUsername(name);
        if (null != userDetails) {
        	if(StringUtils.isNoneBlank(oriCode)) {
        		//oriCode验证是否存在，如果不存在，返回客户端唯一代码不存在。
        		SysOrganization queryRecord=new SysOrganization();
        		queryRecord.setLevel(1);
        		queryRecord.setUniqueCode(oriCode);
        		SysOrganization organzation=organService.selectByOne(queryRecord);
        		if(organzation==null) {
        			throw new PreAuthenticatedCredentialsNotFoundException("客户端唯一代码不存在");
        		}
        		//用户oriCode字段是null,返回该用户不是客户端用户。
        		JwtUser user=(JwtUser)userDetails;
        		if(user.getId()==null) {
        			throw new PreAuthenticatedCredentialsNotFoundException("当前账号不是客户端用户");
        		}
        		//用户oriCode字段和oriCode参数不一样，不是该学校的用户。
        		if(!user.getOriCode().equals(organzation.getId())) {
        			throw new PreAuthenticatedCredentialsNotFoundException("当前账号不是当前学校用户");
        		}
        	}
            if (bCryptPasswordEncoder.matches(password, userDetails.getPassword())) {
            	//我之所以不在这里加载权限是因为我觉得。。没那么多人无聊老是输错密码吧
                Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                return auth;
            } else {
                throw new BadCredentialsException("密码错误");
            }
        } else {
            throw new UsernameNotFoundException("用户不存在");
        }
    }

    /**
     * 是否可以提供输入类型的认证服务
     * @param authentication
     * @return
     */
    @Override
    public boolean supports(Class<?> authentication) {
        return authentication.equals(CustomUsernamePasswordAuthenticationToken.class);
    }
    
    public static void main(String[] args) {
		Integer a = 203;
		Integer b = 203;
		System.out.println(a == b);
	}
}
